<!--
 * @Description: 三级权限组织架构
 * @Author: wind-lc
 * @version: 1.0
 * @Date: 2021-09-14 14:36:27
 * @LastEditTime: 2024-04-02 09:45:55
 * @FilePath: \cscec-pms-admin\src\views\project\projectPlanningAssessment\monthly\PermissionTreeOrganization.vue
-->
<template>
  <div class="permission-tree-organization">
    <a-input-search style="margin-bottom: 8px" placeholder="请搜索" @change="handleChange" />
    <div class="permission-tree-organization-tree">
      <a-spin :spinning="loading">
        <a-tree v-if="treeData.length > 0" :expanded-keys="expandedKeys" :auto-expand-parent="autoExpandParent"
          :tree-data="treeData" :replace-fields="replaceFields" :selected-keys="selectedKeys" @expand="handleExpand"
          @select="handleSelect">
          <!-- <template
            v-if="node.tageCode === 'PD'"
            slot="title"
            slot-scope="node"
          >
            <span v-if="node[replaceFields.title].indexOf(searchValue) > -1">
              {{ node[replaceFields.title].substr(0, node[replaceFields.title].indexOf(searchValue)) }}<span
                style="color: #f50">{{ searchValue }}</span>{{ node[replaceFields.title].substr(node[replaceFields.title].indexOf(searchValue) + searchValue.length) }}
            </span>
            <span v-else>{{ node[replaceFields.title] }}</span>
          </template> -->
          <template slot="title" slot-scope="node">
            <template v-if="node.tageCode === 'PD'">
              <span v-if="node[replaceFields.pdTilte].indexOf(searchValue) > -1">
                {{ node[replaceFields.pdTilte].substr(0, node[replaceFields.pdTilte].indexOf(searchValue)) }}
                <span style="color: #f50">{{ searchValue }}</span>
                  {{node[replaceFields.pdTilte].substr(node[replaceFields.pdTilte].indexOf(searchValue) +searchValue.length)}}
              </span>
              <span v-else>{{ node[replaceFields.pdTilte] }}</span>
            </template>
            <template v-else>
              <span v-if="node[replaceFields.title].indexOf(searchValue) > -1">
                {{ node[replaceFields.title].substr(0, node[replaceFields.title].indexOf(searchValue)) }}
                <span style="color: #f50">{{ searchValue }}</span>{{
                    node[replaceFields.title].substr(node[replaceFields.title].indexOf(searchValue) + searchValue.length)
                }}
              </span>
              <span v-else>{{ node[replaceFields.title] }}</span>
            </template>
          </template>
        </a-tree>
        <a-empty v-else />
      </a-spin>
    </div>
    <span v-if="showPermission" class="permission-tree-organization-btn"
      :style="{ right: collapsed ? 0 : right + 'px' }" @click="handleCollapsed">
      <a-icon v-if="collapsed" type="caret-right" />
      <a-icon v-else type="caret-left" />
    </span>
  </div>
</template>
<script>
import { Empty } from 'ant-design-vue'
import { queryProjectTree } from '@/api/subassembly/TreeSelectOrganization'
export default {
  name: 'PermissionTreeOrganization',
  props: {
    collapsed: {
      type: Boolean,
      default: false
    },
    // 限制树级数,例如不需要显示项目层级传1，默认不限制
    levelLimit: {
      type: [Number, String],
      default: () => -1
    },
    // 是否显示展开收起
    showPermission: {
      type: Boolean,
      default: true
    },
    // 是否禁用父级，只启用末级
    parentDisabled: {
      type: Boolean,
      default: false
    }
  },
  components: {
    AEmpty: Empty
  },
  data() {
    return {
      // 展开节点
      expandedKeys: [],
      // 搜索值
      searchValue: '',
      // 自动展开父节点
      autoExpandParent: true,
      // 数据
      treeData: [],
      // 数据列表
      treeList: [],
      // 数据自动替换
      replaceFields: {
        children: 'childTree',
        title: 'orgName',
        pdTilte: 'projectName',
        key: 'orgId'
      },
      // 加载
      loading: true,
      // 选中项
      selectedKeys: [],
      right: -9
    }
  },
  mounted() {
    this.getData()
  },
  methods: {
    /**
     * @description: 扁平化数据
     * @param {array} data
     * @return {void}
     */
    flatTree(tree, levels = 0) {
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        let level = levels
        node.level = level // 添加树层级
        const key = node[this.replaceFields.key]
        const title = node[this.replaceFields.title]
        node.scopedSlots = { title: 'title' }

        this.treeList.push({ [this.replaceFields.key]: key, [this.replaceFields.title]: title })
        // 若限制层级则去除children
        if (level == this.levelLimit) {
          delete node[this.replaceFields.children]
          continue
        }
        if (node[this.replaceFields.children]) {
          level++
          this.parentDisabled && (node.disabled = true)
          this.flatTree(node[this.replaceFields.children], level)
        }
      }
    },
    /**
     * @description: 搜索父节点
     * @param {string} key
     * @param {array} tree
     * @return {void}
     */
    getParentKey(key, tree) {
      let parentKey
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        if (node[this.replaceFields.children]) {
          if (node[this.replaceFields.children].some((item) => item[this.replaceFields.key] === key)) {
            parentKey = node[this.replaceFields.key]
          } else if (this.getParentKey(key, node[this.replaceFields.children])) {
            parentKey = this.getParentKey(key, node[this.replaceFields.children])
          }
        }
      }
      return parentKey
    },
    /**
     * @description: 搜索改变
     * @param {void}
     * @return {void}
     */
    handleChange(e) {
      const value = e.target.value
      const expandedKeys = this.treeList
        .map((item) => {
          if (item[this.replaceFields.title] && item[this.replaceFields.title].indexOf(value) > -1) {
            return this.getParentKey(item[this.replaceFields.key], this.treeData)
          }
          return null
        })
        .filter((item, i, self) => item && self.indexOf(item) === i)
      Object.assign(this, {
        expandedKeys,
        searchValue: value,
        autoExpandParent: true
      })
    },
    /**
     * @description: 获取数据
     * @param {void}
     * @return {void}
     */
    getData() {
      this.loading = true
      queryProjectTree()
        .then(({ code, data }) => {
          if (code === 200) {
            this.treeData = [data]
            this.flatTree(this.treeData)
            this.selectedKeys = [this.treeData[0].childTree[0][this.replaceFields.key]]
            this.expandedKeys = [this.treeData[0][this.replaceFields.key]]
            this.$emit('init', this.treeData[0])
            this.$emit('select', this.treeData[0].childTree[0])
          } else {
            this.treeData = []
          }
        })
        .finally(() => {
          this.loading = false
        })
    },
    /**
     * @description: 节点展开收缩
     * @param {string} expandedKeys
     * @return {void}
     */
    handleExpand(expandedKeys) {
      this.expandedKeys = expandedKeys
      this.autoExpandParent = false
    },
    /**
     * @description: 树选择
     * @param {array} selectedKeys 选中key
     * @param {array} selectedNodes 选中节点
     * @return {void}
     */
    handleSelect(selectedKeys, { selectedNodes }) {
      this.selectedKeys = selectedKeys
      this.$emit('select', selectedNodes[0]?.data.props || {})
    },
    /**
     * @description: 收缩展开树
     * @param {void}
     * @return {void}
     */
    handleCollapsed() {
      this.$emit('update:collapsed', !this.collapsed)
    }
  }
}
</script>
<style lang="less" scoped>
.permission-tree-organization {
  min-height: calc(var(--heightVh) - 300px);
  position: relative;
  transition: width 0.5s ease;
}

.permission-tree-organization-collapsed {
  width: 0;
}

.permission-tree-organization-tree {
  // overflow-x: hidden;
  overflow-y: auto;

  // height: calc(100vh - 300px);
  &::-webkit-scrollbar {
    background: #fff;
    width: 8px;
    height: 8px;
    // display: none;
  }

  &::-webkit-scrollbar-thumb {
    /*滚动条里面小方块*/
    width: 8px;
    border-radius: 8px;
    border: 1px #fff solid;
    background: #ccc;
  }
}

.permission-tree-organization-btn {
  width: 10px;
  height: 58px;
  position: absolute;
  background-image: url('');
  background-repeat: no-repeat;
  background-position: center;
  top: calc(var(--heightVh) * 0.5 - 184px);
  margin-top: -29px;
  cursor: pointer;
  overflow: hidden;

  .anticon {
    background-color: #f7f7f7;
    position: absolute;
    top: 50%;
    margin-top: -7px;
    left: -3px;
    font-size: 14px;
  }
}
</style>

